package cn.leonis.consumer01.service.impl;

import cn.leonis.consumer01.pojo.Order;
import cn.leonis.consumer01.pojo.Product;
import cn.leonis.consumer01.service.OrderService;
import com.netflix.appinfo.InstanceInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.List;

@Service
public class OrderServiceImpl implements OrderService {

    private final RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @Autowired
    public OrderServiceImpl(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @Override
    public Order selectOrderById(Integer id) {
        return new Order(1, "Tobi", callServiceByLoadBalancerClient());
    }

    /**
     * 调用远程服务返回产品,第一种方式：通过discoveryClient
     * @return
     */
    private List<Product> callService() {

        StringBuffer sb = null;

        // 获取服务列表
        final List<String> services = discoveryClient.getServices();

        if (services.size() <= 0 || services == null) {
            return null;
        }

        // 根据服务名称获取实例
        final List<ServiceInstance> instances = discoveryClient.getInstances("eureka-provider");

        if (instances.size() <= 0 || instances == null) {
            return null;
        }

        final ServiceInstance serviceInstance = instances.get(0);

        System.out.println(serviceInstance);

        sb = new StringBuffer();

        sb.append("http://")
                .append(serviceInstance.getHost())
                .append(":")
                .append(serviceInstance.getPort())
                .append("/product/all");

        ResponseEntity<List<Product>> response = restTemplate
                .exchange(
                        sb.toString(),
                        HttpMethod.GET,
                        null,
                        new ParameterizedTypeReference<List<Product>>() {});
        return response.getBody();
    }

    /**
     * 通过负载均衡获取服务
     * @return
     */
    private List<Product> callServiceByLoadBalancerClient() {

        StringBuffer sb = null;

        // 根据服务名称获取实例
        final ServiceInstance instance = loadBalancerClient.choose("eureka-provider");

        if (instance == null) {
            return null;
        }

        System.out.println(instance);

        sb = new StringBuffer();

        sb.append("http://")
                .append(instance.getHost())
                .append(":")
                .append(instance.getPort())
                .append("/product/all");

        System.out.println(sb.toString());

        ResponseEntity<List<Product>> response = restTemplate
                .exchange(
                        sb.toString(),
                        HttpMethod.GET,
                        null,
                        new ParameterizedTypeReference<List<Product>>() {});
        return response.getBody();
    }

    /**
     * 通过loadbalance注解实现
     * @return
     */
    public List<Product> callServiceByLoadBalanceAnnotation() {
        ResponseEntity<List<Product>> response = restTemplate
                .exchange(
                        "http://eureka-provider/product/all",
                        HttpMethod.GET,
                        null,
                        new ParameterizedTypeReference<List<Product>>() {});
        return response.getBody();
    }
}
